package com.saver.modules.sys.service;

import com.saver.common.db.JdbcTool;
import com.saver.common.utils.DateUtils;
import com.saver.common.utils.PageUtils;
import com.saver.common.utils.Query;
import com.saver.common.utils.R;
import com.saver.modules.sys.dao.SysRoleDao;
import com.saver.modules.sys.dao.SysUserDao;
import com.saver.modules.sys.entity.SysRoleEntity;
import com.saver.modules.sys.entity.SysUserEntity;
import com.saver.modules.sys.form.PasswordForm;
import org.apache.commons.lang.ArrayUtils;
import org.apache.commons.lang.RandomStringUtils;
import org.apache.shiro.crypto.hash.Sha256Hash;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.multipart.MultipartFile;

import java.io.IOException;
import java.util.*;


/**
 * 系统用户
 *
 * @author yuxiaolong
 * @email 1005471232@qq.com
 * @date 2018年08月30日 下午10:45
 */
@Service("sysUserService")
public class SysUserService {

    @Autowired
    private SysUserRoleService sysUserRoleService;

    @Autowired
    private SysUserDao sysUserDao;

    @Autowired
    private SysRoleDao sysRoleDao;

    @Autowired
    private SysRoleService sysRoleService;

    @Autowired
    private JdbcTool jdbcTool;

    public R uploadAvatar(@RequestParam("file") MultipartFile multipartFile, Long userId) {
        try {
            Base64.Encoder encoder = Base64.getEncoder();
            String avatar = encoder.encodeToString(multipartFile.getBytes());
            SysUserEntity sysUserEntity = sysUserDao.findByUserId(userId);
            sysUserEntity.setAvatar(avatar);
            sysUserDao.save(sysUserEntity);
        } catch (IOException e) {
            return R.error("头像上传失败");
        }

        return R.ok();
    }

    public R updatePassword(PasswordForm form, Long userId) {
        if (form.getNewPassword().equals(form.getConfirmPassword())) {
            return R.error("两次密码不一致，请重新输入");
        }

        SysUserEntity byUserId = sysUserDao.findByUserId(userId);
        //sha256加密
        String password = new Sha256Hash(form.getPassword(), byUserId.getSalt(), 10).toHex();

        //sha256加密
        String newPassword = new Sha256Hash(form.getNewPassword(), byUserId.getSalt(), 10).toHex();
        SysUserEntity sysUserEntity = sysUserDao.findByUserIdAndPassword(userId, password);
        if (sysUserEntity != null) {
            sysUserEntity.setPassword(newPassword);
            sysUserDao.save(sysUserEntity);
            return R.ok();
        }
        return R.error("原密码不正确");
    }

    public PageUtils queryPage(Map<String, Object> params, Long userId) {
        Query query = new Query(params);
        String sql = "select user_id userId,username,name,email,mobile,status,create_time createTime from sys_user su";
        String q = (String) params.get("q");
        String username = (String) params.get("username");
        String name = (String) params.get("name");
        String createTime = (String) params.get("createTime");
        if (q != null && !q.equals("")) {
            sql = sql + " where su.username like '%" + q + "%' or name like '%" + q + "%'";
        }
        if (username != null && !username.equals("")) {
            if (sql.contains("where") || sql.contains("WHERE")) {
                sql = sql + " and (su.username like '%" + username + "%') ";
            } else {
                sql = sql + " where (su.username like '%" + username + "%') ";
            }
        }
        if (name != null && !name.equals("")) {
            if (sql.contains("where") || sql.contains("WHERE")) {
                sql = sql + " and (su.name like '%" + name + "%') ";
            } else {
                sql = sql + " where (su.name like '%" + name + "%') ";
            }
        }
        if (sql.contains("where") || sql.contains("WHERE")) {
            if (userId != 1) {
                sql = sql + " and (su.create_user_id = " + userId + ") ";
            }
        } else {
            if (userId != 1) {
                sql = sql + " where (su.create_user_id =" + userId + ") ";
            }
        }
        if (createTime != null && !createTime.equals("")) {
            String[] split = createTime.split(",");
            Date start = new Date(Long.parseLong(split[0]));
            Date end = new Date(Long.parseLong(split[1]));
            String startFormat = DateUtils.format(start, DateUtils.DATE_TIME_PATTERN);
            String endFormat = DateUtils.format(end, DateUtils.DATE_TIME_PATTERN);
            if (sql.contains("where") || sql.contains("WHERE")) {
                sql = sql + " and (su.create_time >= '" + startFormat + "' and su.create_time <='" + endFormat + "')";
            } else {
                sql = sql + " where (su.create_time >= '" + startFormat + "' and su.create_time <='" + endFormat + "')";
            }
        }
        PageUtils pageUtils = jdbcTool.queryPage(sql, query);
        return pageUtils;
    }

    public R info(Long userId, SysUserEntity entity) {
        SysUserEntity user = sysUserDao.findByUserId(userId);
        user.setPassword("");
        user.setPwdCheck("");
        //获取用户所属的角色列表
        List<Map<String, Object>> list = sysRoleService.queryRoleList(userId);
        Set<Long> roleIds = new HashSet();
        list.forEach(item -> {
            roleIds.add(new Long((Integer) item.get("roleId")));
        });
        user.setRoleIds(roleIds);
        if (userId == 1) {
            return R.ok().put("user", user).put("roles", sysRoleDao.findAll());
        }
        Set<Long> rIds = entity.getRoleIds();
        Iterator<Long> iterator = rIds.iterator();
        String s = "";
        while (iterator.hasNext()) {
            s = s + iterator.next() + ",";
        }
        if (s.length() > 0) {
            s = s.substring(0, s.length() - 1);
        }
        List<Map<String, Object>> all = jdbcTool.list("select * from sys_role where role_id in(" + s + ") order by role_id asc");
        return R.ok().put("user", user).put("roles", all);
    }

    @Transactional
    public R save(SysUserEntity user, Long userId) {
        if (!user.getPassword().equals(user.getPwdCheck())) {
            return R.error("两次密码不一致请重新输入");
        }
        user.setCreateUserId(userId);
        user.setCreateTime(new Date());
        //sha256加密
        String salt = RandomStringUtils.randomAlphanumeric(20);
        user.setPassword(new Sha256Hash(user.getPassword(), salt, 10).toHex());
        user.setSalt(salt);
        user.setStatus(1);
        sysUserDao.save(user);
        //保存用户与角色关系
        sysUserRoleService.saveUserRoleSet(user.getRoleIds(), user.getUserId());
        return R.ok();
    }

    @Transactional
    public R update(SysUserEntity user) {
        if (!user.getPassword().equals(user.getPwdCheck())) {
            return R.error("两次密码不一致请重新输入");
        }
        //sha256加密
        String salt = RandomStringUtils.randomAlphanumeric(20);
        user.setPassword(new Sha256Hash(user.getPassword(), salt, 10).toHex());
        user.setSalt(salt);
        sysUserDao.save(user);
        //保存用户与角色关系
        sysUserRoleService.saveUserRoleSet(user.getRoleIds(), user.getUserId());
        return R.ok();
    }

    public R updateStatus(SysUserEntity entity) {
        Long userId = entity.getUserId();
        if (userId == 1) {
            return R.error("超级管理员不能被禁用");
        }
        Integer status = entity.getStatus();
        Optional<SysUserEntity> byId = sysUserDao.findById(userId);
        if (byId.isPresent()) {
            SysUserEntity userEntity = byId.get();
            userEntity.setStatus(status);
            sysUserDao.save(userEntity);
            return R.ok();
        }
        return R.error("用户不存在");
    }

    @Transactional
    public R deleteBatch(Long[] userIds, Long currentUserId) {
        if (ArrayUtils.contains(userIds, 1L)) {
            return R.error("系统管理员不能删除");
        }

        if (ArrayUtils.contains(userIds, currentUserId)) {
            return R.error("当前用户不能删除");
        }
        for (Long aLong : userIds) {
            sysUserDao.deleteById(aLong);
            sysUserRoleService.deleteByUserId(aLong);
        }
        return R.ok();
    }

}
